/*
 * XXX
 */

package edu.uhcl.csci4838.group3.view;

import edu.uhcl.csci4838.group3.pendingIntents.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.channels.FileChannel;

import edu.uhcl.csci4838.group3.R;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.SharedPreferences.Editor;
import android.content.pm.ActivityInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Vibrator;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.widget.ListView;

import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.DropboxAPI.DropboxFileInfo;
import com.dropbox.client2.DropboxAPI.Entry;
import com.dropbox.client2.android.AndroidAuthSession;
import com.dropbox.client2.exception.DropboxException;
import com.dropbox.client2.session.AccessTokenPair;
import com.dropbox.client2.session.AppKeyPair;
import com.dropbox.client2.session.Session.AccessType;

/**
 * XXX
 * 
 * @author XXX
 */
public class SettingsActivity extends ListActivity {
	
	final static private AccessType ACCESS_TYPE = AccessType.APP_FOLDER;
	final static private String ACCOUNT_PREFS_NAME = "prefs";
	final static private String ACCESS_KEY_NAME = "ACCESS_KEY";
	final static private String ACCESS_SECRET_NAME = "ACCESS_SECRET";
	private DropboxAPI<AndroidAuthSession> mDBApi;
	Vibrator vibe;
	
	/**
	 * XXX
	 * 
	 * @param savedInstanceState
	 */
	/* 
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
		setTitle("Settings");
		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		SettingsActivity.this.setProgressBarIndeterminateVisibility(false);
		this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
		this.setContentView(R.layout.activity_settings);
		
		AppKeyPair appKeys = new AppKeyPair(getString(R.string.app_key),
				getString(R.string.app_secret));
		AndroidAuthSession session = buildSession();
		mDBApi = new DropboxAPI<AndroidAuthSession>(session);
		ArrayAdapter adapter = new ArrayAdapter(this,
				R.layout.settingsitem,
				R.id.tv_settingsitem,
				getResources().getStringArray(R.array.settingsViewList));
		setListAdapter(adapter);
	}
	
	/**
	 * XXX
	 * 
	 * @param l
	 * @param v
	 * @param position
	 * @param id
	 */
	/* 
	 * (non-Javadoc)
	 * 
	 * @see android.app.ListActivity#onListItemClick(android.widget.ListView, android.view.View, int, long)
	 */
	
	@Override
	protected void onListItemClick(ListView l,
			View v,
			int position,
			long id) {
		super.onListItemClick(l,
				v,
				position,
				id);
		l.getItemAtPosition(position);
		// add & authenticate the dropbox account
		if (position == 0) {
			SettingsActivity.this.setProgressBarIndeterminateVisibility(true);
			vibe = (Vibrator) getSystemService(VIBRATOR_SERVICE);
			vibe.vibrate(50);
			mDBApi.getSession()
					.startAuthentication(SettingsActivity.this);
		}
		// export database to SD Card
		if (position == 1) {
			Log.d("BackpackEDU",
					"Was okay");
			
			File sd = Environment.getExternalStorageDirectory();
			File data = Environment.getDataDirectory();
			
			if (sd.canWrite()) {
				String currentDBPath = "data"
						+ File.separator
						+ "edu.uhcl.csci4838.group3"
						+ File.separator
						+ "databases"
						+ File.separator
						+ getString(R.string.db_name);
				String backupDBPath = "BackpackEDU";
				File currentDB = new File(data,
						currentDBPath);
				File backupDB = new File(sd,
						backupDBPath);
				
				if (currentDB.exists()) {
					try {
						FileChannel src = new FileInputStream(currentDB).getChannel();
						FileChannel dst = new FileOutputStream(backupDB).getChannel();
						dst.transferFrom(src,
								0,
								src.size());
						src.close();
						dst.close();
						Toast.makeText(this,
								"Backpack successfully backed up to SD card!",
								Toast.LENGTH_LONG)
								.show();
					} catch (FileNotFoundException ex) {
						Toast.makeText(this,
								"Could not find backpack. Make sure it is in the correct location.",
								Toast.LENGTH_LONG)
								.show();
					} catch (IOException ex) {
						Toast.makeText(this,
								"Could not write to SD card. Make sure you have one installed.",
								Toast.LENGTH_LONG)
								.show();
					}
					
					finally {
						AllIntents.setUpAllIntents(this);
					}
					
				} else {
					Toast.makeText(this,
							"Could not find backpack. Make sure it is in the correct location.",
							Toast.LENGTH_LONG)
							.show();
				}
			} else {
				Toast.makeText(this,
						"Could not write to SD card. Make sure you have one installed.",
						Toast.LENGTH_LONG)
						.show();
			}
		}
		
		// export to dropbox
		if (position == 2) {
			SettingsActivity.this.setProgressBarIndeterminateVisibility(true);
			Toast.makeText(this,
					"BackpackEDU is sending the backpack to DropBox...",
					Toast.LENGTH_LONG)
					.show();
			new BackupDBtoDropbox().execute();
			
		}
		
		// import from SD Card
		if (position == 3) {
			final AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setTitle("Be careful:")
			.setMessage("Are you sure you wish to import your backpack from the SD card? This will overwrite the entire current backpack!")
			.setPositiveButton("Import",
						new DialogInterface.OnClickListener() {
							
							@SuppressWarnings("synthetic-access")
							@Override
							public void onClick(final DialogInterface dialog,
									final int which) {
								File sd = Environment.getExternalStorageDirectory();
								File data = Environment.getDataDirectory();
								if (sd.canRead()) {
									
									String currentDBPath = "data"
											+ File.separator
											+ "edu.uhcl.csci4838.group3"
											+ File.separator
											+ "databases"
											+ File.separator
											+ getString(R.string.db_name);
									String backupDBPath = "BackpackEDU";
									File currentDB = new File(data,
											currentDBPath);
									File backupDB = new File(sd,
											backupDBPath);
									if (currentDB.exists()) {
										try {
											AllIntents.cancelAllIntents(SettingsActivity.this);
											FileChannel src = new FileInputStream(backupDB).getChannel();
											FileChannel dst = new FileOutputStream(currentDB).getChannel();
											dst.transferFrom(src,
													0,
													src.size());
											src.close();
											dst.close();
											Toast.makeText(getApplicationContext(),
													"Backpack successfully imported from the SD card!",
													Toast.LENGTH_LONG)
													.show();
										} catch (FileNotFoundException ex) {
											Toast.makeText(getApplicationContext(),
													"Could not find backpack. Make sure it is in the correct location.",
													Toast.LENGTH_LONG)
													.show();
										} catch (IOException ex) {
											Toast.makeText(getApplicationContext(),
													"Could not read from SD card. Make sure you have one installed.",
													Toast.LENGTH_LONG)
													.show();
										}
										
										finally {
											AllIntents.setUpAllIntents(SettingsActivity.this);
										}
										
									} else {
										Toast.makeText(getApplicationContext(),
												"Could not find backpack. Make sure it is in the correct location.",
												Toast.LENGTH_LONG)
												.show();
									}
								} else {
									Toast.makeText(getApplicationContext(),
											"Could not read from SD card. Make sure you have one installed.",
											Toast.LENGTH_LONG)
											.show();
								}
								
							}
			})
	.setNegativeButton(android.R.string.cancel,
			new CancelListener());
final AlertDialog alert = builder.create();
alert.show();
							
			
		}
		
		// import from dropbox
		if (position == 4) {
			final AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setTitle("Be careful:")
			.setMessage("Are you sure you wish to import your backpack from Dropbox? This will overwrite the entire current backpack!")
			.setPositiveButton("Import",
						new DialogInterface.OnClickListener() {
							
							@SuppressWarnings("synthetic-access")
							@Override
							public void onClick(final DialogInterface dialog,
									final int which) {
								SettingsActivity.this.setProgressBarIndeterminateVisibility(true);
								Toast.makeText(getApplicationContext(),
										"BackpackEDU is downloading the backpack from DropBox...",
										Toast.LENGTH_LONG)
										.show();
								new ImportDBfromDropbox().execute();
								
							}
						})
				.setNegativeButton(android.R.string.cancel,
						new CancelListener());
			final AlertDialog alert = builder.create();
			alert.show();
			
		}
		
		// notification settings
		if (position == 5) {
			
			final CharSequence[] items = { "Normal", "Vibrate", "Silent Mode" };
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setTitle("Choose a mode:");
			// XXX TODO
			final SharedPreferences appSettings = getSharedPreferences("AppPreferences",
					MODE_PRIVATE);
			final SharedPreferences.Editor prefEditor = appSettings.edit();
			final int settings = appSettings.getInt("soundSettings",
					0);
			builder.setSingleChoiceItems(items,
					settings,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog,
								int item) {
							prefEditor.putInt("soundSettings",
									item);
							prefEditor.commit();
							dialog.dismiss();
						}
					});
			AlertDialog alert = builder.create();
			alert.show();
		}
		/*
		// pick time interval for rss feed to automatically update
		if (position == 6) {
			final CharSequence[] items = {
					"5 Minutes",
					"10 Minutes",
					"15 Minutes",
					"30 Minutes",
					"1 hours",
					"3 hours",
					"6 hours",
					"1 day",
					"Manual Refresh" };
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setTitle("RSS Update Intervals:");
			final SharedPreferences appSettings = getSharedPreferences("AppPreferences",
					MODE_PRIVATE);
			final SharedPreferences.Editor prefEditor = appSettings.edit();
			final int settings = appSettings.getInt("rssSettings",
					-1);
			builder.setSingleChoiceItems(items,
					settings,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog,
								int item) {
							prefEditor.putInt("rssSettings",
									item);
							prefEditor.commit();
							dialog.dismiss();
						}
					});
			AlertDialog alert = builder.create();
			alert.show();
		}
		
		// manually refresh RSS feed
		if (position == 7) {
			// XXX TODO
		}
		*/
	}
	
	/**
	 * XXX
	 */
	/* 
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onResume()
	 */
	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		
		if (mDBApi.getSession()
				.authenticationSuccessful()) {
			try {
				// MANDATORY call to complete auth.
				// Sets the access token on the session
				mDBApi.getSession()
						.finishAuthentication();
				
				AccessTokenPair tokens = mDBApi.getSession()
						.getAccessTokenPair();
				
				storeKeys(tokens.key,
						tokens.secret);
				
			} catch (IllegalStateException e) {
				Log.i("DbAuthLog",
						"Error authenticating",
						e);
			}
		}
		
	}
	
	private void storeKeys(String key,
			String secret) {
		// Save the access key for later
		SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME,
				0);
		Editor edit = prefs.edit();
		edit.putString(ACCESS_KEY_NAME,
				key);
		edit.putString(ACCESS_SECRET_NAME,
				secret);
		edit.commit();
	}
	
	private String[] getKeys() {
		SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME,
				0);
		String key = prefs.getString(ACCESS_KEY_NAME,
				null);
		String secret = prefs.getString(ACCESS_SECRET_NAME,
				null);
		if (key != null
				&& secret != null) {
			String[] ret = new String[2];
			ret[0] = key;
			ret[1] = secret;
			return ret;
		} else {
			return null;
		}
	}
	
	private AndroidAuthSession buildSession() {
		AppKeyPair appKeyPair = new AppKeyPair(getString(R.string.app_key),
				getString(R.string.app_secret));
		AndroidAuthSession session;
		
		String[] stored = getKeys();
		if (stored != null) {
			AccessTokenPair accessToken = new AccessTokenPair(stored[0],
					stored[1]);
			session = new AndroidAuthSession(appKeyPair,
					ACCESS_TYPE,
					accessToken);
		} else {
			session = new AndroidAuthSession(appKeyPair,
					ACCESS_TYPE);
		}
		
		return session;
	}
	
	/**
	 * XXX
	 */
	/* 
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onRestart()
	 */
	@Override
	protected void onRestart() {
		// TODO Auto-generated method stub
		super.onRestart();
		SettingsActivity.this.setProgressBarIndeterminateVisibility(false);
		
	}
	
	private class BackupDBtoDropbox extends AsyncTask<Void, Void, String> {
		
		/**
		 * XXX
		 * 
		 * @param params
		 * @return
		 */
		/* 
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#doInBackground(Params[])
		 */
		@Override
		protected String doInBackground(Void... params) {
			
			File data = Environment.getDataDirectory();
			String currentDBPath = "data"
					+ File.separator
					+ "edu.uhcl.csci4838.group3"
					+ File.separator
					+ "databases"
					+ File.separator
					+ getString(R.string.db_name);
			File tmpFile = new File(data,
					currentDBPath);
			FileInputStream fis;
			try {
				fis = new FileInputStream(tmpFile);
				DropboxAPI.Entry newEntry = mDBApi.putFileOverwrite("/BackpackEDU",
						fis,
						tmpFile.length(),
						null);
				Entry existingEntry = mDBApi.metadata("/BackpackEDU",
						1,
						null,
						false,
						null);
				Log.i("DbExampleLog",
						"The file's rev is now: "
								+ existingEntry.rev);
				return "Backpack successfully backed up to DropBox!";
			} catch (FileNotFoundException ex) {
				return "Backpack not found.";
				
			} catch (DropboxException ex) {
				return "Could not connect. Make sure you've added a Dropbox account.";
				
			}
			
		}
		
		/**
		 * XXX
		 * 
		 * @param result
		 */
		/* 
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
		 */
		@Override
		protected void onPostExecute(String result) {
			Toast.makeText(SettingsActivity.this,
					result,
					Toast.LENGTH_LONG)
					.show();
			SettingsActivity.this.setProgressBarIndeterminateVisibility(false);
			super.onPostExecute(result);
		}
	}
	
	private class ImportDBfromDropbox extends AsyncTask<Void, Void, String> {
		
		@Override
		protected String doInBackground(Void... params) {
			if (mDBApi.getSession()
					.authenticationSuccessful()) {
				File data = Environment.getDataDirectory();
				String fullPath = "data"
						+ File.separator
						+ "edu.uhcl.csci4838.group3"
						+ File.separator
						+ "databases"
						+ File.separator
						+ getString(R.string.db_name);
				File tmpFile = new File(data,
						fullPath);
				FileOutputStream outputStream;
				try {
					AllIntents.cancelAllIntents(SettingsActivity.this);
					outputStream = new FileOutputStream(tmpFile);
					DropboxFileInfo info = mDBApi.getFile("/BackpackEDU",
							null,
							outputStream,
							null);
					Log.i("DbExampleLog",
							"The file's rev is: "
									+ info.getMetadata().rev);
					return "Backpack successfully downloaded from DropBox!";
				} catch (FileNotFoundException e) {
					return "Could not find your backpack. Please ensure it is in the correct folder.";
					
				} catch (DropboxException e) {
					return "Could not connect. Make sure you've added a Dropbox account.";
					
				} finally {
					AllIntents.setUpAllIntents(SettingsActivity.this);
				}
			} else {
				return "Could not connect. Make sure you've added a Dropbox account.";
			}
		}
		
		// //////////////////////////////////////////////////////////////////////////////////////////////////////
		@Override
		protected void onPostExecute(String result) {
			Toast.makeText(SettingsActivity.this,
					result,
					Toast.LENGTH_LONG)
					.show();
			SettingsActivity.this.setProgressBarIndeterminateVisibility(false);
			super.onPostExecute(result);
		}
	}
	
}
